package com.qf.future;

import com.utils.ExecutorUtils;
import sun.net.www.protocol.http.HttpURLConnection;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.Supplier;

public class Demo {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        ThreadPoolExecutor pool = ExecutorUtils.getExcutorsPool();

        // 这个方法从内部的线程池中申请一个先从去处理任务
//        CompletableFuture.runAsync(() -> {
//            System.out.println(Thread.currentThread().getName() + ":异步执行一个任务。。。。");
//        });
//
//        // 从自己的项目的线程池中申请一个先从处理业务
//        CompletableFuture.runAsync(() -> {
//            System.out.println(Thread.currentThread().getName() + ":异步执行一个任务。。。。");
//        }, ExecutorUtils.getExcutorsPool());


//        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(new Supplier<Integer>() {
//            @Override
//            public Integer get() {
//                return 10 * 10;
//            }
//        }, ExecutorUtils.getExcutorsPool());
//        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
//            int a = 10;
//            int b = 20;
//            return a * b;
//        }, ExecutorUtils.getExcutorsPool());
//        System.out.println("异步返回的结果:" + future.get()); // 也是阻塞方法


        // 一个线程帮我计算 10+10
        // 另一个线程从线程1的返回结果之上*20
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("supplyAsync:第【" + Thread.currentThread().getName() + "】线程开始计算。。。");
            int i = 10 / 0;
            return 10 + 10;
        }, pool)
//                .whenComplete((resp, ex) -> { // 等上面线程执行完后再执行这个线程
//            System.out.println("第【"+Thread.currentThread().getName() +"】resp:" + resp);
//            System.out.println("ex:" + ex);
//        });
                // resp:上一个线程的返回结果
                // ex:上一个线程的异常对象，如果没有异常改参数是null
                .whenCompleteAsync((resp, ex) -> { // 等待上面线程运行完后，从指定的线程池中重新申请一个线程执行
                    System.out.println("whenCompleteAsync:第【" + Thread.currentThread().getName() + "】resp:" + resp);
                    System.out.println("ex:" + ex);
                }, pool)
//                .exceptionally((ex) -> { // 线程出现异常后调用，可以降级，改变线程的返回值
//                    System.out.println("exceptionally:第【" + Thread.currentThread().getName() + "】ex:" + ex);
//                    return 100; // 默认返回值
//                })
                .handleAsync((resp,ex)->{ // 不管是否出现异常都会执行
                    System.out.println("handleAsync:第【" + Thread.currentThread().getName() + "】ex:" + ex);
                    System.out.println("handleAsync:第【" + Thread.currentThread().getName() + "】resp:" + resp);
                    if(ex != null){
                        return 1000;
                    }else{
                        return resp;
                    }
                },pool);

        Integer sum = future.get();
        System.out.println("sum【"+Thread.currentThread().getName()+"】"+sum);
//        System.out.println(Thread.currentThread().getName() + " 主线程");
        pool.shutdown(); // 关闭线程池

    }
}
